#include <streams.h>
#include "..\..\src\ffmpeg-priv.h"
#include "VideoRecHelper.h"
#include "JRtpRecVideo.h"
#include "H263Decodec.h"
CVideoRecHelper::CVideoRecHelper(void)
{

	m_pGraph = NULL;
	m_pControl= NULL;
	m_pNullRenderer= NULL;
	m_pIRender= NULL;
	m_pRtpRec= NULL;

	m_pIDecodec= NULL;
	m_pDecodec= NULL;
}

CVideoRecHelper::~CVideoRecHelper(void)
{
	
	if(m_pControl!=NULL){
	m_pControl->Stop();
	delete m_pControl ;
	}

	if(m_pGraph != NULL)
		delete m_pGraph;
	if(m_pNullRenderer!= NULL)
		delete m_pNullRenderer;
	if(m_pIRender!= NULL)
		delete m_pIRender;
	if(m_pRtpRec!= NULL)
		delete m_pRtpRec;
	if(m_pIDecodec!= NULL)
		delete m_pIDecodec;
	if(m_pDecodec!= NULL)
		delete m_pDecodec;



}

int CVideoRecHelper::init(void)
{

	
	HRESULT hr=m_pGraph.CoCreateInstance(CLSID_FilterGraph);
	if(FAILED(hr))
	{
		return -1;
	}

	hr=m_pGraph.QueryInterface(&m_pControl);
	if(FAILED(hr))
	{
		return -1;
	}
	m_pRtpRec = new CJRtpRecVideo(NULL,&hr);
	m_pRtpRec->AddRef();

	m_pRtpRec->QueryInterface(IID_IBaseFilter,
		(LPVOID *)&m_pIRender);
	if(FAILED(hr))
	{
		return -1;
	}

	hr = m_pGraph->AddFilter(m_pIRender,L"mydesc");


	m_pDecodec = new CH263Decodec(L"H263Decodec",NULL,&hr);
	m_pDecodec->AddRef();

	m_pRtpRec->QueryInterface(IID_IBaseFilter,
		(LPVOID *)&m_pIDecodec);
	if(FAILED(hr))
	{
		return -1;
	}

	hr = m_pGraph->AddFilter(m_pIDecodec,L"mydecodec");

	
	m_pNullRenderer.CoCreateInstance(CLSID_VideoRenderer);
	m_pGraph->AddFilter(m_pNullRenderer,L"render");

	IPin *pPinOut1 = GetPin(m_pIRender, PINDIR_OUTPUT );
	IPin *pPinIn1 =  GetPin(m_pIDecodec, PINDIR_INPUT );

	hr= m_pGraph->Connect(pPinOut1,pPinIn1);
	
	IPin *pPinOut2 = GetPin(m_pIDecodec, PINDIR_OUTPUT );
	IPin * pPinIn2 =  GetPin(m_pNullRenderer, PINDIR_INPUT );

	hr= m_pGraph->Connect(pPinOut2,pPinIn2);
	
	return 0;
}


IPin * CVideoRecHelper::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)   
{   
	BOOL       bFound = FALSE;   
	IEnumPins  *pEnum;   
	IPin       *pPin;   
	// Begin by enumerating all the pins on a filter    
	HRESULT hr = pFilter->EnumPins(&pEnum);   
	if (FAILED(hr))   
	{   
		return NULL;   
	}   

	// Now look for a pin that matches the direction characteristic.    
	// When we've found it, we'll return with it.    
	while(pEnum->Next(1, &pPin, 0) == S_OK)   
	{   
		PIN_DIRECTION PinDirThis;   
		pPin->QueryDirection(&PinDirThis);   
		if (bFound = (PinDir == PinDirThis))   
			break;   
		pPin->Release();   
	}   
	pEnum->Release();   
	return (bFound ? pPin : NULL);     
} 
int CVideoRecHelper::RunVideoRecGraph(RtpSession* session)
{

	this->m_pRtpRec ->setRtpSession(session);
	
	m_pControl->Run();

	CComQIPtr< IVideoWindow, &IID_IVideoWindow > pWindow = m_pNullRenderer;
	if( pWindow !=NULL )
	{
	HWND hwndPreview = window_id;
	if(hwndPreview!=NULL)
	{
		HWND hwndPreview = (HWND)window_id;
		RECT rc;
		::GetWindowRect( hwndPreview, &rc );
		int twidth=rc.right-rc.left;
		int theight=rc.bottom-rc.top;

		HRESULT hr = pWindow->put_Owner( (OAHWND) hwndPreview );
		hr = pWindow->put_Left(0);
		hr = pWindow->put_Top(0);
		hr = pWindow->put_Width(twidth);
		hr = pWindow->put_Height(theight);
		//pWindow->put_WindowStyleEx(WS_EX_TOPMOST);
		hr = pWindow->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS |WS_BORDER);
		hr = pWindow->put_Visible( OATRUE );
	}

	}
	return 0;
}
